﻿#ifndef LineFinderH
#define LineFinderH

#include <algorithm>
#include "Const.h"

struct Posi
{
    int st, end;
    int len() const { return end - st + 1; }
};

//  每一个表头数字
struct Flag
{
    int n;        // 数量
    int pos;      // -1 : 未解出； >=0 : 解出的起始位置
    bool ok() const { return pos >= 0; }
    int nextpos() const { return pos + n; }
};

//  每一行或列的表头数字
struct Flags
{
    Flag f[maxF];
    int len;
    bool needProc;   //  需要下次处理标志
    void clear() { needProc = true; for (Flag& i : f) i.pos = -1; }
    // 反转flags
    Flags& reverse() { for (int i = 0, j = len - 1; i < j; ++i, --j) std::swap(f[i].n, f[j].n); return *this; }
};

class Line
{
public:
    Cell* workLine;
    int workLineLen, stepCount;

    inline int leftSeek(const Posi& wp, Cell c) const;
    inline int leftSeekN(const Posi& wp, Cell c) const;
    inline int rightSeek(const Posi& wp, Cell c) const;
    inline int rightSeekN(const Posi& wp, Cell c) const;
    void fillPos(int pos, Cell c);
    void fillPosNoEx(int pos) { if (pos >= 0 && pos < workLineLen) fillPos(pos, Cell::No); }    //  判断边界
    void fillPos(const Posi& wp, Cell c) { for (int i = wp.st; i <= wp.end; ++i) fillPos(i, c); }
};

class LineFinder : private Line
{
private:
    Flags* workFlags;
    Posi recuFp;
    int validWlst, recuWlend, recuWlRightYes;
    int recuPos[maxF], sign[maxF], mostRight[maxF];
    unsigned int countLine[maxN];

    bool procSpec(const Posi& wp, Flag& flag);                              //  需要再次处理返回 true
    bool procFirstLast(Posi wp, Flag& flagFirst, Flag& flagLast);           //  同上
    int recursion(int curWp, int curFp);                // 递归完成返回 0, 未解出任何格子返回 1，超过最大递归数返回 2，下同
    int procExhaust(const Posi& wp, const Posi& fp);    // 同上

public:
    unsigned int exhaNum;
    int procALine(Cell* wl, int wlen, Flags& flags);
};

#endif

